// CyTargetLinker RIN conversion,
//
// scripts to create RIN network files for several online databases
// can be used with the CyTargetLinker app for Cytoscape
//
// Copyright 2011-2013 Department of Bioinformatics - BiGCaT, Maastricht University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package cytargetlinker.conversion;

import java.io.File;
import java.io.PrintWriter;
import java.util.List;
import java.util.logging.Logger;

import uk.co.flamingpenguin.jewel.cli.ArgumentValidationException;
import uk.co.flamingpenguin.jewel.cli.CliFactory;
import uk.co.flamingpenguin.jewel.cli.Option;
import cytargetlinker.conversion.graph.Graph;
import cytargetlinker.conversion.graph.XGMMLWriter;

/**
 * Commonly used command line arguments to be parsed.
 * @author Thomas
 */
public class ArgsParser {
	private final static Logger log = Logger.getLogger(ArgsParser.class.getName());
	
	public static <A> A parse(String[] args, Class<? extends A> c) throws ArgumentValidationException {
		return CliFactory.parseArguments(c, args);
	}

	public interface AHelp {
		@Option(helpRequest = true, shortName = "h")
		boolean getHelp();
	}
	
	public interface AFilesIn {
		@Option(shortName = "i", description = "The path to the input file.")
		public File getInput();
		public boolean isInput();
	}
	
	public interface AFilesOut {
		@Option(shortName = "o", description = "The output GML file or directory to write the network(s) to.")
		public File getOutput();
		public boolean isOutput();
	}

	public interface AFilesAttributes {
		@Option(shortName = "n", description = "The name of the network.")
		public String getName();
		public boolean isName();
		
		@Option(shortName = "a", description = "Annotation file")
		public String getAnnotationFile();
		public boolean isAnnotationFile();
		
		@Option(longName = "m", description = "BridgeDb mapping files")
		public List<File> getBridgeDbFiles();
		public boolean isBridgeDbFiles();
		
		@Option(longName = "organism", description = "BridgeDb mapping file")
		public String getOrganism();
		public boolean isOrganism();
		
		@Option(shortName = "s", description = "TFe sources (auto or user)")
		public String getSource();
		public boolean isSource();
		
		@Option(shortName = "l", description = "The path to the log file.")
		public File getLogFile();
		public boolean isLogFile();
		
		@Option(shortName = "d", description = "Description.")
		public String getDescription();
		public boolean isDescription();
		
		@Option(shortName = "f", description = "TF Family file")
		public File getTFFamilyFile();
		public boolean isTFFamilyFile();
	}
	
	public interface GraphBuilder {
		public Graph buildGraph(File in) throws Exception;
	}
	
	private interface GraphWriter {
		public void write(Graph g, PrintWriter out) throws Exception;
	}
	
	private static class XGMML implements GraphWriter {
		public void write(Graph g, PrintWriter out) throws Exception { XGMMLWriter.write(g, out); }
	}
	
	public static void convertAndWrite(AFilesIn fi, AFilesOut fo, GraphBuilder gb) throws Exception {
		GraphWriter writer = new XGMML();
		
		File input = fi == null ? null : fi.getInput();
			
		File output = fo.isOutput() ? fo.getOutput() : new File(fi.getInput().getAbsolutePath() + ".xgmml");
		log.info("Converting " + input + " to " + output + "\n");
		Graph g = gb.buildGraph(input);
		PrintWriter po = new PrintWriter(output);
		writer.write(g, po);
		po.close();
	}
}